/*
 * @Author: your name
 * @Date: 2021-10-27 08:11:56
 * @LastEditTime: 2022-04-04 11:06:41
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: \phone\src\second_view.cpp
 */
#include "second_view.h"
#include "common.h"
#include "gui_engine.h"
#include "xlog.h"
#include <stack>
std::stack<std::string> pagestack;

SecondView::SecondView(const unsigned int itemTotal, std::unique_ptr<Widget>& page)
    : primaryWidget(page)
    , ITEM_TOTAL(itemTotal)
{
    selectLoop = true;
    funcSelected = 0;
    lastSelected = 0;
    funcAmount = 0;
}
/**
 * @brief
 * 异步打开一个新窗口
 * @param win 窗口名称
 * @param event 新窗口按键功能映射表
 * @param page 新窗口PageHandle句柄
 * @param ctx 新窗口上下文，只传递指针值，不进行指针管理，调用者外部自行管理该指针。
 */
bool SecondView::OpenNewPage(std::string win, KeyCmdMapTable event, PageHandle* page, void* ctx, bool repetion)
{
    class Ctx : public Context {
    public:
        Ctx(std::string window, PageHandle* p, KeyCmdMapTable event, void* data, bool rep)
            : win(window)
            , keyCmd(event)
            , page(p)
            , repetion(rep)
        {
            ctx = data;
            repetion = false;
        }
        std::string win;
        KeyCmdMapTable keyCmd;
        PageHandle* page;
        bool repetion;
    };
    if (!page) {
        LOG_E("nullptr page.\n");
        return false;
    }
    Ctx* p = new Ctx(win, page, event, ctx, repetion);
    auto funCallback = [](void* ctx) mutable {
        IS_VALID_PTR(ctx)
        Ctx* p2 = (Ctx*)ctx;
        // KEYEVENT2 event;
        PageHandle* window = Interface::GetInstance().GetCurrentWin(p2->win.c_str());
        /**
         * @brief
         * 当窗口被设置为不可重复打开且当前窗口已经是目标窗口时，不打开窗口
         */
        if (p2->repetion && !window) {
            LOG_W("page is opened.\n");
            delete window;
            delete p2;
            return;
        }
        window = (PageHandle*)p2->page;
        if (!window->PageOpen(p2->win.c_str())) {
            LOG_E("window open error\n");
            delete window;
            delete p2;
            return;
        }
        window->SetKeyEvent(p2->keyCmd);
        window->SaveContext(p2);
        SecondView* p = dynamic_cast<SecondView*>(window);
        if (p) {
            p->StartDisplayV2(p2->ctx);
            p->KeyOkEvent(nullptr);
        }
        Interface::GetInstance().SetCurrentPage(window);
    };
    p->eventCallback = funCallback;
    if (!GuiEngine::GetInstance().IdleQueue(p)) {
        LOG_W("IdleQueue_V2 falied\n");
        delete p;
        return false;
    }
    return true;
}
void SecondView::SecondPageReset(SecondPage* value)
{
    std::lock_guard<std::mutex> locker(m_mutex);
    KeyCmdMapTable event = keyEvent;
    /**
     * @brief
     * 抽象流程：重置设置项按键功能映射表。
     */
    if (value) {
        value->ResetKeyCmd(event);
    }
    secondPage.reset(value);
    PrimaryPageRecover();
}
/**
 * @brief
 * 用引用不方便指针转换。
 * @return SecondPage&
 */
SecondPage& SecondView::GetSecondPage()
{
    std::lock_guard<std::mutex> locker(m_mutex);
    return *secondPage.get();
}
SecondPage* SecondView::ReturnSecondPage()
{
    return secondPage.get();
}
bool SecondView::SecondPageValid()
{
    if (secondPage.get()) {
        return true;
    } else {
        // LOG_W("invalid second page\n");
        return false;
    }
}
bool SecondView::SwitchSelectedItemHandle(Widget* window, int funcSelected, int lastSelected)
{
    return CommonFunc::GetInstance().SwitchSelectedItem(window, funcSelected, lastSelected);
}
bool SecondView::CreateItemHandleV3(unsigned int itemNum, Widget* window, int funcSelected, Widget* view2)
{
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(window, "itemView", true, view.get())) {
        if (GuiEngine::GetInstance().ViewCreate(view.get(), 0, 0, 0, 0, view2)) {
            char name[16] = { 0 };
            sprintf(name, "item%d", funcSelected);
            GuiEngine::GetInstance().SetName(view2, name);
            LOG_I("================name = %s\n", name);
            GuiEngine::GetInstance().SetSelfLayout(view2, "default(w=1769,h=113)");
            GuiEngine::GetInstance().SetChildrenLayout(view2, "default(c=0,r=1)");
            return true;
        }
    }
    LOG_E("create view failed\n");
    return false;
}
void SecondView::DestroyHandle(Widget* window, int itemNum)
{
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(window, "itemView", true, view.get())) {
        char name2[16] = { 0 };
        sprintf(name2, "item%d", itemNum);
        LOG_I("item destroy=%s\n", name2);
        std::unique_ptr<Widget> view6(GuiEngine::GetInstance().NewWidget());
        if (GuiEngine::GetInstance().Lookup(view.get(), name2, true, view6.get())) {
            GuiEngine::GetInstance().Destroy(view6.get());
        }
    }
}
void SecondView::StartDisplayHandle(Widget* window, int funcSelected, std::function<void(Widget*, int)> createOne, unsigned int maxItem)
{
    char name[16] = { 0 };
    char params[64] = { 0 };
    // Widget *window = GetThisPage();
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(window, "itemView", true, view.get())) {
        LOG_I("find view, create the item %\n");
        for (unsigned int i = 0; i < 4; i++) {
            if (i >= maxItem) {
                break;
            }
            std::unique_ptr<Widget> view2(GuiEngine::GetInstance().NewWidget());
            if (GuiEngine::GetInstance().ViewCreate(view.get(), 0, 0, 0, 0, view2.get())) {
                name[0] = 0;
                params[0] = 0;
                sprintf(name, "item%d", funcSelected + i);
                GuiEngine::GetInstance().SetName(view2.get(), name);
                sprintf(params, "default(x=0,y=%d,w=1194,h=200)", i * 202);
                LOG_I("params = %s\n", params);
                GuiEngine::GetInstance().SetSelfLayout(view2.get(), params);
                GuiEngine::GetInstance().SetChildrenLayout(view2.get(), "default(c=0,r=1)");
                if (i == 0) {
                    // 选中第一个
                    GuiEngine::GetInstance().UseStyle(view2.get(), ITEM_FOCUS);
                } else {
                    GuiEngine::GetInstance().UseStyle(view2.get(), ITEM);
                }
                // TODO:bug，funcSelected不能单纯相加
                createOne(view2.get(), i);
            }
        }
    } else {
        LOG_E("can't find item view\n");
    }
}
void SecondView::StartDisplayHandleV2(Widget* window, int funcSelected, std::function<void(Widget*, int)> createOne, unsigned int maxItem)
{
    char name[16] = { 0 };
    // char params[64] = {0};
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(window, "itemView", true, view.get())) {
        LOG_I("find view, create the item %\n");
        for (unsigned int i = 0; i < 6; i++) {
            if (i >= maxItem) {
                break;
            }
            std::unique_ptr<Widget> view2(GuiEngine::GetInstance().NewWidget());
            if (GuiEngine::GetInstance().ViewCreate(view.get(), 0, 0, 0, 0, view2.get())) {
                name[0] = 0;
                // params[0] = 0;
                sprintf(name, "item%d", funcSelected + i);
                GuiEngine::GetInstance().SetName(view2.get(), name);
                // sprintf(params, "default(x=0,y=%d,w=1194,h=200)", i * 202);
                // LOG_I("params = %s\n", params);
                GuiEngine::GetInstance().SetSelfLayout(view2.get(), "default(w=1769,h=113)");
                GuiEngine::GetInstance().SetChildrenLayout(view2.get(), "default(c=0,r=1)");
                if (i == 0) {
                    // 选中第一个
                    GuiEngine::GetInstance().UseStyle(view2.get(), ITEM_FOCUS);
                } else {
                    GuiEngine::GetInstance().UseStyle(view2.get(), ITEM);
                }
                // TODO:bug，funcSelected不能单纯相加
                createOne(view2.get(), i);
            }
        }
    } else {
        LOG_E("can't find item view\n");
    }
}
void SecondView::RefreshItemHandle(void* ctx, void (*func)(void*))
{
    // IS_VALID_PTR(ctx)
    /**
     * @brief
     * p 指针将在回调函数里面释放
     */
    Context* p = new Context;
    p->eventCallback = func;
    if (ctx) {
        KeyboardValue* p2 = new KeyboardValue;
        KeyboardValue key = KeyboardValue::KEYBOARD_VALUE_END;
        ((Context*)ctx)->GetData(key);
        *p2 = key;
        p->ctx = p2;
    }
    if (!GuiEngine::GetInstance().IdleQueue(p)) {
        LOG_W("IdleQueue_V2 falied\n");
        delete p;
    }
}
bool SecondView::SwitchSelectedItem()
{
    if (!GetPrimaryPage()) {
        LOG_E("something wrong happened.\n");
        return false;
    }
    return SwitchSelectedItemHandle(primaryWidget.get(), static_cast<int>(funcSelected), static_cast<int>(lastSelected));
}
void SecondView::RefreshItemIQ3(void* ctx)
{
    /**
     * @brief
     * 如果当前item集合里面包含了切换的下一个item内容，直接切换即可
     * 否则先创建下一页item，再进行切换，翻页的效果
     */
    if (!SwitchSelectedItem()) {
        IS_VALID_PTR(ctx)
        ContextV2<KeyboardValue>* pFunc = (ContextV2<KeyboardValue>*)ctx;
        // RefreshItemData data;
        // pFunc->GetDataV2(data);
        /**
         * @brief
         * 如果没有找到下一个item，先创建下一页item
         */
        CreateItemsHandleV3(pFunc->data);
        SwitchSelectedItem();
    }
}
void SecondView::CreateItemsHandleV3(KeyboardValue key)
{
    if (0 == funcAmount) {
        return;
    }
    Context ctx;
    /**
     * @brief
     * 设置项总数
     */
    unsigned int funcMax = funcAmount;
    unsigned int create = lastSelected;
    KeyboardValue key2;
    if (!GetPrimaryPage()) {
        LOG_E("can't create itme view.\n");
        return;
    }
    if (key == KeyboardValue::KEY_DIRECTION_LEFT || key == KeyboardValue::KEY_DIRECTION_UP) {
        key2 = KeyboardValue::KEY_DIRECTION_LEFT;
        /**
         * @brief
         * 反向换页时，保证按升序排布，先降序
         */
        ctx.ctx = &key2;
        unsigned int total = ITEM_TOTAL;
        if ((lastSelected) == 0) {
            /**
             * @brief
             * 最后一页可能不满屏
             */
            total = funcMax % ITEM_TOTAL == 0 ? ITEM_TOTAL : funcMax % ITEM_TOTAL;
        }
        for (unsigned int i = 0; i <= total; i++) {
            CommonFunc::GetInstance().FunctionSelection(create, funcMax, &ctx);
            if ((create) == 0) {
                CommonFunc::GetInstance().FunctionSelection(create, funcMax, &ctx);
                break;
            }
        }
    }
    /**
     * @brief
     * 一次性销毁所有的item:destroy名称为"itemView"的view控件
     */
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), "itemView", true, view.get())) {
        GuiEngine::GetInstance().Destroy(view.get());
    }
    /**
     * @brief
     * 此处按升序创建每个设置项的item，布局方式由xml文件设置，多态管理不同的派生类要求。
     */
    std::unique_ptr<Widget> view2(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().ViewCreate(primaryWidget.get(), 0, 0, 0, 0, view2.get())) {
        SetItemView(view2.get());
        key2 = KeyboardValue::KEY_DIRECTION_RIGHT;
        ctx.ctx = &key2;
        CommonFunc::GetInstance().FunctionSelection(create, funcMax, &ctx);
        for (unsigned int i = 0; i < ITEM_TOTAL; i++) {
            /**
             * @brief
             * 虚拟功能是否存在，不使用虚拟功能时，忽略此判断
             */
            if (!TargetItemValid(create)) {
                break;
            }
            if (CreateItemView(create, view2.get())) {
                GuiEngine::GetInstance().UseStyle(view2.get(), ITEM);
                CreateOneItem(view2.get(), create);
                EnterItemHandle(create);
            }
            if (create == funcMax - 1) {
                break;
            }
            CommonFunc::GetInstance().FunctionSelection(create, funcMax, &ctx);
        }
    }
}
void SecondView::RefreshItem(void* ctx)
{
    IS_VALID_PTR(ctx)
    class Ctx : public ContextV2<KeyboardValue> {
    public:
        Ctx(std::string window, KeyboardValue key)
            : ContextV2(key)
            , win(window)
        {
        }
        std::string win;
    };
    auto funCallback = [](void* ctx) {
        // IS_VALID_PTR(ctx)
        // Ctx *pFunc = (Ctx *)ctx;
        // // std::lock_guard<std::mutex> locker(Interface::GetInstance().PageProtect());
        // PAGE *window = (PAGE *)Interface::GetInstance().GetCurrentWin(pFunc->win.c_str());
        // IS_VALID_PTR(window)
        // window->RefreshItemIQ3(ctx);
        // delete pFunc;
    };
    KeyboardValue key = KeyboardValue::KEYBOARD_VALUE_END;
    ((Context*)ctx)->GetData(key);
    Ctx* p = new Ctx(primaryWidget->Name(), key);
    p->eventCallback = funCallback;
    /**
     * @brief
     * 取消队列方式，解决程序时序异常问题。
     */
    // if (!GuiEngine::GetInstance().IdleQueue(p))
    // {
    //     LOG_W("IdleQueue_V2 falied\n");
    //     delete p;
    // }
    RefreshItemIQ3(p);
    delete p;
}
void SecondView::RefreshSlider()
{
    if (0 == funcAmount) {
        return;
    }
    int value = 0;
    std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
    if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), "slider", true, view.get())) {
        /**
         * @brief
         * 虚拟功能是否存在，不使用虚拟功能时，忽略此判断;
         * 如果存在虚拟设置项，value的计算由派生类返回。
         */
        if (!VirtualSliderValue(value, funcSelected)) {
            /**
             * @brief
             * 如果显示的所有item里面找到选择的下一个item，直接修改item属性进行选定
             */
            // int tmp = funcAmount;
            // if (tmp - 1 == 0)
            // {
            //     return;
            // }
            // // TODO: 百分比计算待优化
            // value = (100 / (tmp - 1)) * funcSelected;
            // if (tmp / 100 > 0)
            // {
            //     int one = tmp / 100;          //单位1大小
            //     value = (funcSelected) / one; //总共多少份
            // }
            double tmp = funcAmount;
            double test = 0;
            if (tmp - 1 > 0) {
                test = (funcSelected) / (tmp - 1);
            }
            value = int(test * 100);
        }
        value = 100 - value;
        /**
         * @brief
         * 设置项总数可能无法被100整除，这里做简单的修正，放置选中最后一个设置项时，滚动条未滚动到底。
         */
        // if (value <= 5)
        // {
        //     value = 0;
        // }
        GuiEngine::GetInstance().SliderSetValue(view.get(), value);
    }
}
void SecondView::EnterItemHandle(unsigned int target)
{
    std::map<unsigned int, Item*>::iterator iter;
    iter = itemPtr.find(target);
    if (iter != itemPtr.end()) {
        if (!itemPtr[target]->GetEnterItem()) {
            return;
        }
        std::unique_ptr<Widget> view6(GuiEngine::GetInstance().NewWidget());
        char name2[16] = { 0 };
        snprintf(name2, 16, "item%d", target);
        if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), name2, true, view6.get())) {
            std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
            if (GuiEngine::GetInstance().Lookup(view6.get(), "setItem", true, view.get())) {
                GuiEngine::GetInstance().SetSelfLayout(view.get(), "default(w=87%)");
            }
            if (GuiEngine::GetInstance().Lookup(view6.get(), "valueString", true, view.get())) {
                GuiEngine::GetInstance().SetSelfLayout(view.get(), "default(w=1%)");
            }
        }
        /**
         * @brief
         * 抽象流程，特殊设置项初始化
         */
        itemPtr[target]->EnterItemSpecialInit();
    }
}
void SecondView::KeyOkEvent(void* ctx)
{
    // IS_VALID_PTR(ctx)
    auto funCallback = [](void* ctx) {
        IS_VALID_PTR(ctx)
        ContextV2<std::string>* pFunc = (ContextV2<std::string>*)ctx;
        std::string data = pFunc->data;
        // pFunc->GetDataV2(data);
        // std::lock_guard<std::mutex> locker(Interface::GetInstance().PageProtect());
        PageHandle* window = (PageHandle*)Interface::GetInstance().GetWinByName(data.c_str());
        IS_VALID_PTR(window)
        /**
         * @brief
         * 默认把所有按键重定向到设置项实例处理。
         * 暂未使用，框架设计，不要删除
         */
#if 0
            for (int i = 0; i < static_cast<int>(KeyboardValue::KEYBOARD_VALUE_END); i++)
            {
                window->KeyEventRedefine(static_cast<KeyboardValue>(i), KeyCmd::KEY_CMD_CONTRL_SECOND_PAGE);
            }
#endif
        /**
         * @brief
         * 调用设置项绑定的功能函数，有可能包括恢复按键重定向到界面功能（一般指打开新的界面或者设置项只读等情况）
         */
        SecondView* p = dynamic_cast<SecondView*>(window);
        if (p && !p->KeyCmdResetHandle()) {
            /**
             * @brief
             * 如果设置项是只读的，或者初始化异常，恢复界面按键功能。
             */
            window->UnlockSecondPage(nullptr);
        }
        delete pFunc;
    };
    std::string pageName = primaryWidget->Name();
    ContextV2<std::string>* p = new ContextV2<std::string>(pageName);
    p->eventCallback = funCallback;
    /**
     * @brief Construct a new fun Callback object
     * 按键事件，取消队列操作，代码保留===========================
     */
    // funCallback(p);
    if (!GuiEngine::GetInstance().IdleQueue(p)) {
        LOG_W("IdleQueue_V2 falied\n");
        delete p;
    }
    /**
     * @brief Construct a new fun Callback object
     * 按键事件，取消队列操作，代码保留===========================
     */
}
std::string SecondView::GetString(unsigned int target)
{
    std::map<unsigned int, Item*>::iterator iter;
    iter = itemPtr.find(target);
    if (iter != itemPtr.end()) {
        return itemPtr[target]->GetString();
    } else {
        LOG_E("something wrong happen\n");
        return "error";
    }
}
std::string SecondView::GetStringTrText(unsigned int target)
{
    std::map<unsigned int, Item*>::iterator iter;
    iter = itemPtr.find(target);
    if (iter != itemPtr.end()) {
        return itemPtr[target]->GetStringTrText();
    } else {
        LOG_E("something wrong happen\n");
        return "error";
    }
}
std::string SecondView::GetTrText(unsigned int target)
{
    std::map<unsigned int, Item*>::iterator iter;
    iter = itemPtr.find(target);
    if (iter != itemPtr.end()) {
        return itemPtr[target]->GetTrText();
    } else {
        LOG_E("something wrong happen\n");
        return "error";
    }
}
void SecondView::RefreshAllItem()
{
    if (0 == funcAmount) {
        return;
    }
    char name2[16] = { 0 };
    std::unique_ptr<Widget> view6(GuiEngine::GetInstance().NewWidget());
    for (unsigned int i = 0; i < funcAmount; i++) {
        name2[0] = 0;
        snprintf(name2, 16, "item%d", i);
        if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), name2, true, view6.get())) {
            std::map<unsigned int, Item*>::iterator iter;
            iter = itemPtr.find(i);
            if (iter == itemPtr.end()) {
                continue;
            }
            std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
            if (GuiEngine::GetInstance().Lookup(view6.get(), "valueString", true, view.get())) {
                GuiEngine::GetInstance().SetTextUtf8(view.get(), itemPtr[i]->GetString().c_str());
            }
            if (GuiEngine::GetInstance().Lookup(view6.get(), "setItem", true, view.get())) {
                GuiEngine::GetInstance().SetTextUtf8(view.get(), itemPtr[i]->GetTrText().c_str());
            }
            itemPtr[i]->EnterItemSpecialInit();
        }
    }
}
void SecondView::RefreshCurrentItem(unsigned int selected)
{
    if (0 == funcAmount) {
        return;
    }
    constexpr int BUFF = 16;
    /**
     * @brief
     * 刷新的第一个设置项。
     */
    unsigned int start = selected - selected % ITEM_TOTAL;
    char name2[BUFF] = { 0 };
    std::unique_ptr<Widget> view6(GuiEngine::GetInstance().NewWidget());
    for (unsigned int i = start; i < funcAmount; i++) {
        name2[0] = 0;
        snprintf(name2, BUFF, "item%d", i);
        if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), name2, true, view6.get())) {
            // std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
            // if (GuiEngine::GetInstance().Lookup(view6.get(), "valueString", true, view.get())) {
            //     std::map<unsigned int, Item*>::iterator iter;
            //     iter = itemPtr.find(i);
            //     if (iter != itemPtr.end()) {
            //         GuiEngine::GetInstance().SetTextUtf8(view.get(), itemPtr[i]->GetString().c_str());
            //     }
            // }
            std::map<unsigned int, Item*>::iterator iter;
            iter = itemPtr.find(i);
            if (iter == itemPtr.end()) {
                continue;
            }
            std::unique_ptr<Widget> view(GuiEngine::GetInstance().NewWidget());
            if (GuiEngine::GetInstance().Lookup(view6.get(), "valueString", true, view.get())) {
                GuiEngine::GetInstance().SetTextUtf8(view.get(), itemPtr[i]->GetString().c_str());
            }
            if (GuiEngine::GetInstance().Lookup(view6.get(), "setItem", true, view.get())) {
                GuiEngine::GetInstance().SetTextUtf8(view.get(), itemPtr[i]->GetTrText().c_str());
            }
            itemPtr[i]->EnterItemSpecialInit();
        }
        if (ITEM_TOTAL == i % ITEM_TOTAL + 1) {
            break;
        }
    }
    SwitchSelectedItem();
    RefreshSlider();
}
void SecondView::Select(void* ctx)
{
    if (0 == funcAmount) {
        return;
    }
    // unsigned int tmp = lastSelected;
    lastSelected = funcSelected;
    CommonFunc::GetInstance().FunctionSelection(funcSelected, funcAmount, ctx);
    /**
     * @brief
     * 虚拟功能是否存在，不使用虚拟功能时，忽略此判断;
     * 设置项不存在，恢复到上一个状态，虚拟功能不支持循环选择；
     */
    // if (!TargetItemValid(funcSelected))
    // {
    //     funcSelected = lastSelected;
    //     lastSelected = tmp;
    //     return;
    // }
    if (!selectLoop) {
        /**
         * @brief
         * 不允许循环切换
         */
        if (!(funcSelected + 1 == lastSelected || lastSelected + 1 == funcSelected)) {
            funcSelected = lastSelected;
            return;
        }
    }
    RefreshItem(ctx);
    RefreshSlider();
    ItemEvent();
}
void SecondView::StartDisplay()
{
    if (0 == funcAmount) {
        return;
    }
    KeyboardValue key = KeyboardValue::KEY_DIRECTION_RIGHT;
    Context ctx;
    ctx.ctx = &key;
    // funcSelected = 0;
    // lastSelected = funcAmount - 1;
    StartInitFunc();
    RefreshItem(&ctx);
    RefreshSlider();
}
void SecondView::StartDisplayV2(void* ctx)
{
    StartDisplay();
}
bool SecondView::KeyCmdResetHandle()
{
    std::map<unsigned int, std::function<void()>>::iterator iter;
    iter = reset.find(funcSelected);
    if (iter != reset.end()) {
        /**
         * @brief
         * 调用设置项绑定的功能函数。
         */
        reset[funcSelected]();
        char name2[16] = { 0 };
        sprintf(name2, "item%d", funcSelected);
        std::unique_ptr<Widget> view6(GuiEngine::GetInstance().NewWidget());
        if (GuiEngine::GetInstance().Lookup(primaryWidget.get(), name2, true, view6.get())) {
            /**
             * @brief
             * 把view控件设置为选中状态
             */
            if (SecondPageValid()) {
                GetSecondPage().SetContrlView(view6.get());
                /**
                 * @brief Construct a new Item Selected object
                 * 设置项被选中处理，抽象流程，根据具体情况处理。
                 */
                GetSecondPage().ItemSelected();
            }
#if 0
            /**
             * @brief 
             * 设置设置项处于输入（当前设置）状态时的属性，如果选择状态即输入状态，可忽略该过程。
             * 这行代码属于架构性代码，不要轻易删掉。
             */
            GuiEngine::GetInstance().UseStyle(view6.get(), ITEM_SET);
#endif
            /**
             * @brief
             * 通用设置，可在界面窗口属性重写属性实现不同的界面效果
             * 抽象流程。
             */
            SetSelectedItem(view6.get());
        }
        return true;
    } else {
        /**
         * @brief
         * 只读的参数没有reset功能映射，无需做任何处理
         */
        // LOG_W("something wrong happen, ignore if setting item is read-only\n");
        // ItemSelectedHandle();
        return false;
    }
}
void SecondView::UnlockSecondPageV2(void* ctx)
{
    LOG_I("unlock second page\n");
    // KEYEVENT defaultEvent;
    PageHandle* window = (PageHandle*)Interface::GetInstance().GetWinByName(primaryWidget->Name().c_str());
    // IS_VALID_PTR(window)
    if (window) {
        window->SetKeyEvent(keyEvent);
        if (SecondPageValid()) {
            GetSecondPage().ContrlSecondPage(ctx);
        }
    }
    SecondPageReset(nullptr);
}
Widget* SecondView::GetPrimaryPage()
{
    return primaryWidget.get();
}
void SecondView::SetFuncAmount(unsigned int amount)
{
    funcAmount = amount;
}
unsigned int SecondView::GetFuncAmount()
{
    return funcAmount;
}
void SecondView::SetSecondViewKeyEvent(KeyCmdMapTable event)
{
    keyEvent = event;
}
void SecondView::SetItemTotal(unsigned int total)
{
    ITEM_TOTAL = total;
}
void SecondView::StartInitFunc()
{
    funcSelected = 0;
    lastSelected = funcAmount - 1;
}